#include "LString.h"

namespace ln
{
    std::string UTF16ToUTF8(const std::wstring &ws)
    {
        if (ws.empty()) {
            return std::string("");
        }
        std::string s = "";

        if (!ws.empty()) {
            int n = ::WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), NULL, 0, 0, 0);
            if (n > 0) {
                s.resize(n);
                ::WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), (char *)&s.at(0), n, 0, 0);
            }
        }

        return s;
    }

    std::string UTF16ToGBK(const std::wstring &ws)
    {
        if (ws.empty()) {
            return std::string("");
        }
        std::string s;
        int n = ::WideCharToMultiByte(936, 0, ws.c_str(), ws.size(), NULL, 0, 0, 0);
        if (n > 0) {
            s.resize(n);
            ::WideCharToMultiByte(936, 0, ws.c_str(), ws.size(), (char *)&s.at(0), n, 0, 0);
        }

        return s;
    }

    std::wstring UTF8ToUTF16(const std::string &s)
    {
        if (s.empty()) {
            return std::wstring(L"");
        }
        std::wstring ws = L"";

        if (!s.empty()) {
            int n = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), NULL, 0);
            if (n > 0) {
                ws.resize(n);
                ::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), (wchar_t *)&ws.at(0), n);
            }
        }

        return ws;
    }

    std::wstring GBKToUTF16(const std::string &s)
    {
        if (s.empty()) {
            return std::wstring(L"");
        }
        std::wstring ws;
        int n = MultiByteToWideChar(936, 0, s.c_str(), s.size(), NULL, 0);

        if (n > 0) {
            ws.resize(n);
            ::MultiByteToWideChar(936, 0, s.c_str(), s.size(), (wchar_t *)&ws.at(0), n);
        }

        return ws;
    }

    std::string UTF8ToGBK(const std::string &utf8)
    {
        return UTF16ToGBK(UTF8ToUTF16(utf8));
    }

    std::string GBKToUTF8(const std::string &gbk)
    {
        return UTF16ToUTF8(GBKToUTF16(gbk));
    }

    int ToLower(int c)
    {
        if (c >= 'A' && c <= 'Z') {
            return c + 'a' - 'A';
        }
        return c;
    }


    std::wstring ToLower(const std::wstring &s)
    {
        std::wstring t(s);
        for (int i = 0; i < t.size(); ++i) {
            t[i] = ToLower(t[i]);
        }

        return t;
    }

    std::wstring GetShortPath(const std::wstring &path)
    {
        wchar_t name[MAX_PATH];
        int len = GetShortPathNameW(path.c_str(), name, MAX_PATH);
        if (len != 0) {
            return std::wstring(name);
        }
        return path;
    }

    std::wstring RemoveEndSlash(const std::wstring &str)
    {
        int end_index = 0;

        for (int i = str.size()-1; i >= 0; --i) {
            if (str[i] != '\\') {
                end_index = i;
                break;
            }
        }
        if (end_index > 0) {
            return str.substr(0, end_index+1);
        } else {
            return std::wstring(L"");
        }
    }
   
    std::string JoinCmdToFile(int argc, char **argv)
    {
        std::string path;

        for (int i = 0; i < argc; ++i) {
            path += std::string(argv[i]) + std::string(" ");
        }
        path.resize(path.size()-1);
        return path;
    }

    std::wstring JoinDirAndFile(const wchar_t *path, const wchar_t *file)
    {
        std::wstring result(path);
        
     
        if (result[result.length() - 1] != L'\\') {
            result += L'\\';
        }
        result += std::wstring(file);
        return result;
    }

    std::wstring JoinDirAndFile(const std::wstring &path, const std::wstring &file)
    {
        return JoinDirAndFile(path.c_str(), file.c_str());
    }

    std::wstring GetFileShortName(const std::wstring &fileName)
    {
        int lastIndex = fileName.rfind(L"\\");

        if (lastIndex ==-1)
            return std::wstring(fileName);

        return fileName.substr(lastIndex + 1);
    }

    std::wstring GetFileNoExpanName(const std::wstring &file_name)
    {
        int startIndex = file_name.rfind(L"\\");
        int endIndex = file_name.rfind(L".");

        if (startIndex != -1) {

            if (endIndex != -1) {
                return file_name.substr(startIndex + 1, endIndex - startIndex - 1);

            } else {
                return file_name.substr(startIndex + 1);
            }
        }
        return std::wstring(file_name);
    }

    std::wstring GetFolderName(const std::wstring &fileName)
    {
        int lastIndex = fileName.rfind(L"\\");

        if (lastIndex == -1)
            return fileName;

        return fileName.substr(0, lastIndex);
    }

    std::wstring GetExtendName(const std::wstring &filename)
    {
        int lastIndex=filename.rfind(L".");

        if (lastIndex==-1 || lastIndex == filename.length()-1)
            return L"";

        return filename.substr(lastIndex+1);
    }

    std::wstring GetSmallDirctory(const std::wstring &allpathname)
    {
        std::wstring path = RemoveEndSlash(allpathname);

        if (path.length() < 2)
            return path;

        int lastIndex = path.rfind(L"\\");

        if (lastIndex == -1)
            return path;

        return path.substr(lastIndex + 1, path.size() - lastIndex - 1);
    }

    std::wstring ConvertToWString(int value)
    {
        wchar_t buf[100];
        _itow_s(value, buf, 100, 10);
        return std::wstring(buf);
    }

    int ConvertToInt(const std::string &str)
    {
        return atoi(str.c_str());
    }

    int ConvertToInt(const std::wstring &str)
    {
        return _wtoi(str.c_str());
    }

    long ConvertToLong(const std::string &str)
    {
        return atol(str.c_str());
    }
}